/*
 * JFugue - API for Music Programming
 * Copyright (C) 2003-2008  David Koelle
 *
 * http://www.jfugue.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

package org.jfugue;

/**
 * Represents key signature changes. Key signatures are kept for the whole song,
 * independent of tracks. You may change the key signature during a song. The
 * Player will automatically adjust note values based on the current key
 * signature - for example, in an F Major key signature, B will be converted to
 * B-flat automatically, unless the B is noted as a natural B (i.e., "Bn")
 *
 * @author David Koelle
 * @version 3.0
 */
public final class KeySignature implements JFugueElement {
	private byte keySig;
	private byte scale;

	/**
	 * Creates a new key signature object, with the specified tempo value.
	 * 
	 * @param keySig
	 *            the key signature for this object, -7 to +7 - see MIDI
	 *            specification for more details
	 * @param scale
	 *            whether this is a major (0) or minor (1) key signature
	 */
	public KeySignature(byte keySig, byte scale) {
		setKeySig(keySig);
		setScale(scale);
	}

	/**
	 * Sets the key signature, from -7 to +7, for this object. See the MIDI
	 * specification for more details
	 * 
	 * @param keySig
	 *            the key signature for this object
	 */
	public void setKeySig(byte keySig) {
		this.keySig = keySig;
	}

	/**
	 * Sets the scale - 0 for major, 1 for minor. See the MIDI specification for
	 * more details
	 * 
	 * @param scale
	 *            the scale for this object
	 */
	public void setScale(byte scale) {
		this.scale = scale;
	}

	/**
	 * Returns the key signature for this object.
	 * 
	 * @return the key signature for this object
	 */
	public byte getKeySig() {
		return this.keySig;
	}

	/**
	 * Returns the scale for this object.
	 * 
	 * @return the scale for this object
	 */
	public byte getScale() {
		return this.scale;
	}

	/**
	 * Returns the Music String representing this element and all of its
	 * settings. For a key signature object, the Music String is <code>K</code>
	 * <i>keysig</i>, where 'keysig' is a root note followed by 'maj' or 'min'
	 * (i.e., Cbmaj for C-flat major)
	 * 
	 * @return the Music String for this element
	 */
	@Override
	public String getMusicString() {
		StringBuilder keySigSB = new StringBuilder();
		keySigSB.append("K");
		if (scale == 0) {
			keySigSB.append(majorSigs[getKeySig() + 7]);
			keySigSB.append("maj");
		} else {
			keySigSB.append(minorSigs[getKeySig() + 7]);
			keySigSB.append("min");
		}
		return keySigSB.toString();
	}

	/**
	 * Returns verification string in this format: KeySig: keySig={#}, scale={#}
	 * 
	 * @version 4.0
	 */
	@Override
	public String getVerifyString() {
		StringBuffer buffy = new StringBuffer();
		buffy.append("KeySig: keySig=");
		buffy.append(getKeySig());
		buffy.append(", scale=");
		buffy.append(getScale());
		return buffy.toString();
	}

	private static final String[] majorSigs = new String[] { "Cb", "Gb", "Db",
			"Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#" };
	private static final String[] minorSigs = new String[] { "Ab", "Eb", "Bb",
			"F", "C", "G", "D", "A", "E", "B", "F#", "C#", "G#", "D#", "A#" };
}